const API = {
  db: {
    dbUrl: "mongodb://127.0.0.1:27017",
    dbName: 'trobl'
  }
}

const {MongoClient} = require('mongodb')
class Db {
  dbClient = null
  dbUrl
  dbName
  /**
   * 单例 用于保存数据库对象
   * @param dbUrl 数据库连接地址
   * @param dbName 库名
   * @returns {Db} 数据库对象
   */
  static getInstance(dbUrl, dbName) {
    if (!Db.instance) {
      Db.instance = new Db(dbUrl, dbName)
    }
    return Db.instance
  }
  constructor(dbUrl, dbName) {
    this.dbUrl = dbUrl
    this.dbName = dbName
    this.connect()
  }

  /**
   * 连接数据库
   */
  connect() {
    return new Promise((resolve, reject) => {
      if (this.dbClient) {
        resolve(this.dbClient)
      }
      MongoClient.connect(this.dbUrl, {useUnifiedTopology: true}, (err, client) => {
        if (err) {
          reject(err)
        }
        this.dbClient = client.db(this.dbName)
        resolve(this.dbClient)
      })
    })
  }

  /**
   *
   * @param tablename 表明
   * @param json 查询条件
   * @param order 排序条件, { key: 1/-1 }，key: 排序字段key，1 / -1 1升序，-1降序
   * @returns {Promise<object>} 数据
   */
  find(tablename, json, order = { order: 1 }) {
    return new Promise((resolve, reject) => {
      this.connect()
        .then(db => {
          const result = db.collection(tablename).find(json).sort(order)
          result.toArray((err, data) => {
            if (err) {
              reject(err)
            }
            resolve(data)
          })
        })
        .catch(err => {
          reject(err)
        })
    })
  }

  /**
   * 删除数据
   * @param tablename 表名
   * @param json 删除条件
   * @returns {Promise<object>} 是否成功
   */
  deleteOne(tablename, json) {
    return new Promise((resolve, reject) => {
      this.connect()
        .then(db => {
          db.collection(tablename).deleteOne(json, (err, data) => {
            if (err) {
              reject(err)
            }
            resolve(data)
          })
        })
        .catch(err => {
          reject(err)
        })
    })
  }

  /**
   * 插入数据
   * @param tablename 表名
   * @param json 插入的数据
   * @returns {Promise<object>} 是否成功
   */
  insertOne(tablename, json) {
    return new Promise((resolve, reject) => {
      this.connect()
        .then(db => {
          db.collection(tablename).insertOne(json, (err, data) => {
            if (err) {
                reject(err)
            }
            resolve(data)
          })
        })
        .catch(err => {
          reject(err)
        })
    })
  }

  /**
   * 修改数据
   * @param tablename 表名
   * @param qjson 查询条件
   * @param json 进行修改
   * @returns {Promise<any>} 是否成功
   */
  updateOne(tablename, qjson, json) {
    return new Promise((resolve, reject) => {
      this.connect()
        .then(db => {
          db.collection(tablename).updateOne(qjson, json, (err, data) => {
            if (err) {
                reject(err)
            }
            resolve(data)
          })
        })
        .catch(err => {
          reject(err)
        })
    })
  }
}

module.exports = Db.getInstance(API.db.dbUrl, API.db.dbName)
